/*
 * @Name:ajax
 * @Descripttion: 接口请求
 * @Author: 无痕
 * @Date: 2020-05-19 11:43:47
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2020-07-08 13:24:02
 */

import Config from '@/config';
import Store from '@/store';
import { extend, toast } from '@/utils';

// loading
const Loading = (() => {
  let count = 0;
  let timer = null;
  return {
    show (title, loadingTime) {
      clearTimeout(timer);
      timer = setTimeout(() => {
        count++;
        uni.showLoading({
          title,
          mask: true
        });
      }, loadingTime);
    },
    hide () {
      clearTimeout(timer);
      if (count > 0 && !--count) {
        uni.hideLoading();
      }
    }
  };
})();

// ajax请求失败状态码翻译
const ajaxFailStatusEnum = {
  400: '请求错误',
  401: '没有权限',
  403: '拒绝访问',
  404: '请求地址未发现',
  405: '请求方法未允许',
  406: '请求的格式不可得',
  408: '请求超时',
  410: '请求的资源被删除',
  422: '验证错误',
  500: '服务器端出错',
  501: '网络未实现',
  502: '网络错误',
  503: '服务不可用',
  504: '网络超时'
};

function Ajax (options = {}) {
  options = extend(true, {
    header: {},
    method: 'GET', // 请求方式
    showLoading: true, // 是否显示加载loading
    loadingText: '请求中...', // loading 文字
    dataType: 'json',
    responseType: 'text',
    loadingTime: 200, // 在此时间内，请求还没回来的话，就显示加载中动画，单位ms
    showError: true // 是否显示错误提示
  }, options);

  // token等验证信息
  options.data = extend({}, options.data, {
    // token: 'xxx'
  });
  // 判断url是否是带域名的绝对路径
  if (!/^(https|http)/.test(options.url)) {
    options.url = Config.host + options.url;
  }
  // loading
  if (options.showLoading) {
    Loading.show(options.loadingText, options.loadingTime);
  }
  // 返回promise
  return new Promise(resolve => {
    options.complete = response => {
      // 关闭loading
      options.showLoading && Loading.hide();
      // 接口全部resolve处理
      if (response.statusCode == 200) {
        // 过滤统一局部返回
        const res = response.data;
        const code = res.code;
        const msg = res.msg || '请求异常';
        if (code == '200') {
          resolve({ ok: true, code, data: res.data, msg });
        } else {
          resolve({ ok: false, code, msg });
        }
      } else {
        const code = response.statusCode || 500;
        const msg = ajaxFailStatusEnum[code] || '请求异常';
        if (options.showError) {
          toast(msg);
        }
        resolve({ ok: false, code, msg });
      }
    };
    uni.request(options);
  });
}

// 暴露快捷定义接口方法方式
export const [Get, Post, Put, Delete] = ['get', 'post', 'put', 'delete'].map(k => {
  const method = k.toUpperCase();
  Ajax[method] = (url, data, others) => Ajax({
    method,
    url,
    data,
    ...others
  });
  return url => (data, others) => Ajax[method](url, data, others);
});

export default Ajax;
